package Ptolemaiosz;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.logging.Logger;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;

public class Initializer {

	private int lastLevel;
	private Application application;
        public View view;

    public Initializer() {
        
        	SkeletonLogger.logCall();
				
		SkeletonLogger.logReturn();
    }
        
        public void setApplication(Application a)
        {
            	SkeletonLogger.logCall();
		
		
		SkeletonLogger.logReturn();
            application = a;
        }
        

	public void loadNextLevel() {
            
            
            
		SkeletonLogger.logCall();
		
                loadLevel(lastLevel+1);
                
                 
		SkeletonLogger.logReturn();
	}

	public void restartLevel() {
            
            System.err.println("retsart called");
                //Kimenet
                 //Controller.println("palya ujrainditva");
            
		SkeletonLogger.logCall();
		
                     loadLevel(lastLevel);
                     
		SkeletonLogger.logReturn();
             }

	/**
	 * 
	 * @param levelNumber
	 */
	public void loadLevel(int levelNumber) {
		SkeletonLogger.logCall();
		//aktualis palya szamanak elmentese fajlba
		try
                {
			FileOutputStream fileOut = new FileOutputStream("level.sav");
			ObjectOutputStream out = new ObjectOutputStream(fileOut);
			out.writeObject(levelNumber);
			out.close();
			fileOut.close();
		}catch(IOException i)
		{
			i.printStackTrace();
		}


                //Folyamat elindulasanak jelzese
                //Controller.println("Betoltottem a(z) " + levelNumber + ". palyat");
                
                //Float formazo inicializalasa
                NumberFormat  float2tizedes = NumberFormat.getInstance();
                float2tizedes.setMinimumFractionDigits(2);
                float2tizedes.setMaximumFractionDigits(2);
                
                ///////////////////////////////
                // XML BEOLVASASA
                ///////////////////////////////
                
                try
                    {
                        //Reader inicializalasa
                        File fXmlFile = new File("maps/map" + levelNumber + ".xml");
                        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                        org.w3c.dom.Document doc = dBuilder.parse(fXmlFile);
                        doc.getDocumentElement().normalize();                        
                        
                        ////////////////////////
                        // Level
                        //////////////////////// 
                        Level level = new Level();
                           level.setApplication(application);
                           
                           
                           
                        ////////////////////////
                        // Default poligon
                        //////////////////////// 
                        CustomPolygon Default2W6HPolygon = new CustomPolygon();
                            Default2W6HPolygon.addVertex(new Vector(-1.00f, -3.00f));
                            Default2W6HPolygon.addVertex(new Vector( 1.00f, -3.00f));
                            Default2W6HPolygon.addVertex(new Vector( 1.00f, 3.00f));
                            Default2W6HPolygon.addVertex(new Vector(-1.00f, 3.00f));
                           
                        ////////////////////////
                        // LEVELKPARTOK
                        ////////////////////////                       
                        
                        //2DNeighBourArray letrehozasa
                            ArrayList<ArrayList<LevelPart>> NeighBourArray2D = new ArrayList<ArrayList<LevelPart>>();
                            
                            //Maximum 10 sor magas lehet a palyaszakaszok tombje
                            for(int i = 0 ; i < 10;i++ )
                                NeighBourArray2D.add(new ArrayList<LevelPart>());
                            
                        //Levelparok kiolvasasa
                        NodeList levelparts = doc.getElementsByTagName("levelpart");
                        
                        //Minden egyes levelpartra
                        for(int i = 0; i < levelparts.getLength();i++)
                                {
                                    //Az egyes attributumok beolvasasa
                                    NamedNodeMap attributes = levelparts.item(i).getAttributes();
                                    int id = Integer.parseInt(attributes.getNamedItem("id").getNodeValue());
                                    int row = Integer.parseInt(attributes.getNamedItem("postionRow").getNodeValue());
                                    int col = Integer.parseInt(attributes.getNamedItem("positionColumn").getNodeValue());
                                    
                                    //Uj LevelPart Letrehozasa
                                    LevelPart newLevelPart = new LevelPart();
                                    newLevelPart.setId(id);
                                    
                                    //Uj levelPart Eltarolasa
                                    NeighBourArray2D.get(row).add(col, newLevelPart);
                                    
                                    //Emptylevelpart attributum lekezelese
                                    if(attributes.getNamedItem("empty") != null)
                                        {
                                            if(attributes.getNamedItem("empty").getNodeValue().equals("true"))
                                            {
                                                level.setEmptyLevelPart(newLevelPart);                                                
                                            }
                                            
                                        }
                                    
                                    //Kimenet
                                    //Controller.println("\tPalyaszakasz letrehozva || ID = " + NeighBourArray2D.get(row).get(col).getId() +"; Row = " + row + "; Col = " + col);
                                }
                        
                        ////////////////////////
                        // KULCSOK
                        //////////////////////// 
                        int numberOfKeys = 0; 
                        
                        
                        //Kulcsok kiolvasasa
                        NodeList keys = doc.getElementsByTagName("key");
                        
                        //Minden egyes kulcsra
                        for(int i = 0; i < keys.getLength();i++)
                                {
                                    //Az egyes attributumok beolvasasa
                                    NamedNodeMap attributes = keys.item(i).getAttributes();
                                    float positionX = Float.parseFloat(attributes.getNamedItem("positionX").getNodeValue());
                                    float positionY = Float.parseFloat(attributes.getNamedItem("positionY").getNodeValue());
                                    int levelPartId = Integer.parseInt(attributes.getNamedItem("levelpartID").getNodeValue());
                                    
                                                               
                                    //Uj Key Letrehozasa
                                    Key key1 = new Key();
                                            PhysicalEntity keyphy1 = new PhysicalEntity();
                                                keyphy1.setPosition(new Vector(positionX, positionY));
                                                keyphy1.setPolygon(Default2W6HPolygon);
                                                keyphy1.setLevelPartManager(application.getLevelPartManager());
                                        key1.setPhysicalEntity(keyphy1);
                                        key1.setLevel(level);
                                    
                                    //Uj Key Eltarolasa
                                        //Adott ID-val rendelkezo levelpart kikeresese
                                            int searchID = levelPartId;
                                            LevelPart foundLevelPart = null;
                                            
                                            int row = 0; int col = 0;
                                            
                                            while(foundLevelPart == null)
                                                {                                                   
                                                   if(NeighBourArray2D.get(row).get(col).getId() == searchID)
                                                       foundLevelPart = NeighBourArray2D.get(row).get(col);
                                                   
                                                   //Ha meg lehet oldalra menni a tombben akkor megyunk oldalra
                                                   if(col < NeighBourArray2D.get(row).size()-1)
                                                        {
                                                            col++;
                                                        }
                                                   else
                                                        {
                                                            //Ha mar nem lehet oldalra menni, de lefele meg lehet
                                                            if(row < NeighBourArray2D.size()-1)
                                                                {
                                                                    row++;
                                                                    col = 0;
                                                                }
                                                        }
                                                }
                                            //A megtalalt levelparthoz hozzadjuk a kulcsot
                                            foundLevelPart.addElement(key1);  
                                            
                                   //Kimenet
                                   //Controller.println("\tKulcs letrehozva PalyaszakaszID: " + foundLevelPart.getId() + " Position: (" + float2tizedes.format(key1.getPhysicalEntity().getPosition().getX()).replace(',','.') + ", " + float2tizedes.format(key1.getPhysicalEntity().getPosition().getY()).replace(',','.') + ")");
;                                   
                                   //Kulcsok szamanak megnovelese
                                   numberOfKeys++;

                                }
                        
                        //Kulcsok szamanak a rogzitese
                        level.setNumberOfKeys(numberOfKeys);


                        ////////////////////////
                        // AJTO
                        //////////////////////// 
                        
                        //ajtok kiolvasasa
                        NodeList doors = doc.getElementsByTagName("door");
                        
                        //Minden egyes ajtora
                        for(int i = 0; i < doors.getLength();i++)
                                {
                                    //Az egyes attributumok beolvasasa
                                    NamedNodeMap attributes = doors.item(i).getAttributes();
                                    float positionX = Float.parseFloat(attributes.getNamedItem("positionX").getNodeValue());
                                    float positionY = Float.parseFloat(attributes.getNamedItem("positionY").getNodeValue());
                                    int levelPartId = Integer.parseInt(attributes.getNamedItem("levelpartID").getNodeValue());

                                    //Uj door Letrehozasa
                                    Door door = new Door();
                                        PhysicalEntity doorphy = new PhysicalEntity();
                                            doorphy.setPosition(new Vector(positionX, positionY));
                                            doorphy.setPolygon(Default2W6HPolygon);
                                            doorphy.setLevelPartManager(application.getLevelPartManager());
                                    door.setPhysicalEntity(doorphy);
                                    door.setLevel(level);    
                                        
                                    //Uj Door Eltarolasa
                                        //Adott ID-val rendelkezo levelpart kikeresese
                                            int searchID = levelPartId;
                                            LevelPart foundLevelPart = null;
                                            
                                            int row = 0; int col = 0;
                                            
                                            while(foundLevelPart == null)
                                                {                                                   
                                                   if(NeighBourArray2D.get(row).get(col).getId() == searchID)
                                                       foundLevelPart = NeighBourArray2D.get(row).get(col);
                                                   
                                                   //Ha meg lehet oldalra menni a tombben akkor megyunk oldalra
                                                   if(col < NeighBourArray2D.get(row).size()-1)
                                                        {
                                                            col++;
                                                        }
                                                   else
                                                        {
                                                            //Ha mar nem lehet oldalra menni, de lefele meg lehet
                                                            if(row < NeighBourArray2D.size()-1)
                                                                {
                                                                    row++;
                                                                    col = 0;
                                                                }
                                                        }
                                                }
                                            //A megtalalt levelparthoz hozzadjuk a kulcsot
                                            foundLevelPart.addElement(door);  
                                            
                                   //Kimenet
                                   //Controller.println("\tAjto letrehozva PalyaszakaszID: " + foundLevelPart.getId() + " Position: (" + float2tizedes.format(door.getPhysicalEntity().getPosition().getX()).replace(',','.') + ", " + float2tizedes.format(door.getPhysicalEntity().getPosition().getY()).replace(',','.') + ")");
;
                                }
                        
                        
                        ////////////////////////
                        // AVATAROK
                        //////////////////////// 
                        
                        //avatarok kiolvasasa
                        NodeList avatars = doc.getElementsByTagName("avatar");
                        
                        //Minden egyes avatarra
                        for(int i = 0; i < avatars.getLength();i++)
                                {
                                    //Az egyes attributumok beolvasasa
                                    NamedNodeMap attributes = avatars.item(i).getAttributes();
                                    
                                    int id = Integer.parseInt(attributes.getNamedItem("id").getNodeValue());
                                    float positionX = Float.parseFloat(attributes.getNamedItem("positionX").getNodeValue());
                                    float positionY = Float.parseFloat(attributes.getNamedItem("positionY").getNodeValue());
                                    int levelPartId = Integer.parseInt(attributes.getNamedItem("levelpartID").getNodeValue());

                                    //Uj Avatar Letrehozasa
                                    Avatar avatar =  new Avatar();
                                            AvatarPhysicalEntity avatarphy = new AvatarPhysicalEntity();
                                                avatarphy.setPosition(new Vector(positionX, positionY));
                                                avatarphy.setPolygon(Default2W6HPolygon);
                                                avatarphy.setLevelPartManager(application.getLevelPartManager());
                                            avatar.setPhysicalEntity(avatarphy);  
                                            
                                        
                                    //Uj Avatar Eltarolasa
                                        //Adott ID-val rendelkezo levelpart kikeresese
                                            int searchID = levelPartId;
                                            LevelPart foundLevelPart = null;
                                            
                                            int row = 0; int col = 0;
                                            
                                            while(foundLevelPart == null)
                                                {                                                   
                                                   if(NeighBourArray2D.get(row).get(col).getId() == searchID)
                                                       foundLevelPart = NeighBourArray2D.get(row).get(col);
                                                   
                                                   //Ha meg lehet oldalra menni a tombben akkor megyunk oldalra
                                                   if(col < NeighBourArray2D.get(row).size()-1)
                                                        {
                                                            col++;
                                                        }
                                                   else
                                                        {
                                                            //Ha mar nem lehet oldalra menni, de lefele meg lehet
                                                            if(row < NeighBourArray2D.size()-1)
                                                                {
                                                                    row++;
                                                                    col = 0;
                                                                }
                                                        }
                                                }
                                            //A megtalalt levelpartot megadjuk az avatarnak
                                            avatar.setCurrentLevelPart(foundLevelPart);
                                            
                                            //Avatar eltarolasa
                                            level.addAvatar(avatar,id);
                                            
                                              
                                            
                                   //Kimenet
                                   //Controller.println("\tAvatar letrehozva AvatarID: " + id  + " PalyaszakaszID: " + avatar.getCurrentLevelPart().getId() + " Position: (" + float2tizedes.format(avatar.getPhysicalEntity().getPosition().getX()).replace(',','.') + ", " + float2tizedes.format(avatar.getPhysicalEntity().getPosition().getY()).replace(',','.') + ")");
                                }
                        
                        ////////////////////////
                        // Falak
                        //////////////////////// 
                        
                        //avatarok kiolvasasa
                        NodeList walls = doc.getElementsByTagName("wall");
                        
                        //Minden egyes avatarra
                        for(int i = 0; i < walls.getLength();i++)
                                {
                                    //Az egyes attributumok beolvasasa
                                    NamedNodeMap attributes = walls.item(i).getAttributes();

                                    float positionX = Float.parseFloat(attributes.getNamedItem("positionX").getNodeValue());
                                    float positionY = Float.parseFloat(attributes.getNamedItem("positionY").getNodeValue());
                                    int levelPartId = Integer.parseInt(attributes.getNamedItem("levelpartID").getNodeValue());

                                    //Uj fal Letrehozasa         
                                   Wall wall1 = new Wall();
                                    WallPhysicalEntity wallphy1 = new WallPhysicalEntity();
                                        wallphy1.setPosition(new Vector(positionX, positionY));
                                        wallphy1.setLevelPartManager(application.getLevelPartManager());
                                    
                                        
                                    //Kimenet
                                    //Controller.println("\tWall letrehozva PalyaszakaszID: " + levelPartId + " Position: ("+ float2tizedes.format(wallphy1.getPosition().getX()).replace(',','.') +", " + float2tizedes.format(wallphy1.getPosition().getY()).replace(',','.') +")");
                                    //Controller.println("\t\tPoligon letrehozasa:");    
                                        
                                    //Letrehozzuk a poligonjat
                                        CustomPolygon wall1Poligon = new CustomPolygon();
                                            //Kikeressuk a csucsokat
                                                NodeList vertexes = walls.item(i).getChildNodes().item(1).getChildNodes();
                                                
                                                for(int j = 0; j < vertexes.getLength();j++)
                                                  {
                                                      if(vertexes.item(j).getNodeName() == "vertex")
                                                      {
                                                         NamedNodeMap VertexAttributes = vertexes.item(j).getAttributes();

                                                         float VertexPositionX = Float.parseFloat(VertexAttributes.getNamedItem("positionX").getNodeValue());
                                                         float VertexPositionY = Float.parseFloat(VertexAttributes.getNamedItem("positionY").getNodeValue());
                                                         
                                                         //Csucs hozzadasa
                                                         wall1Poligon.addVertex(new Vector(VertexPositionX, VertexPositionY));
                                                         
                                                         //Kimeneten valo jelzes
                                                         //Controller.println("\t\t\tvertex letrehozva Position: (" + float2tizedes.format(VertexPositionX).replace(',','.')  +", " + float2tizedes.format(VertexPositionY).replace(',','.')  +")");
                                                        }
                                                  }
                                                
                                    //Poligon hozzadasa a fizikiai entitashoz
                                    wallphy1.setPolygon(wall1Poligon);
                                        
                                    //Fizikai es a logikai entitasok osszerendelese
                                    wall1.setPhysicalEntity(wallphy1);
                                            
                                        
                                    //Uj fal Eltarolasa
                                        //Adott ID-val rendelkezo levelpart kikeresese
                                            int searchID = levelPartId;
                                            LevelPart foundLevelPart = null;
                                            
                                            int row = 0; int col = 0;
                                            
                                            while(foundLevelPart == null)
                                                {                                                   
                                                   if(NeighBourArray2D.get(row).get(col).getId() == searchID)
                                                       foundLevelPart = NeighBourArray2D.get(row).get(col);
                                                   
                                                   //Ha meg lehet oldalra menni a tombben akkor megyunk oldalra
                                                   if(col < NeighBourArray2D.get(row).size()-1)
                                                        {
                                                            col++;
                                                        }
                                                   else
                                                        {
                                                            //Ha mar nem lehet oldalra menni, de lefele meg lehet
                                                            if(row < NeighBourArray2D.size()-1)
                                                                {
                                                                    row++;
                                                                    col = 0;
                                                                }
                                                        }
                                                }

                                            //A megtalalt levelpartnak atadjuk a falat
                                            foundLevelPart.addWall(wall1);
                                            foundLevelPart.addElement(wall1); //Sima elementkent is at kell adni!
                                            
                                }
                        
                        
                        
                                                
                        ////////////////////////
                        // Egyeb osszerendelesek
                        //////////////////////// 
                        
                        level.setneighbour2DArray(NeighBourArray2D);
                        
                        application.setLevel(level);
                        application.getPhysics().setLevel(level);
                        application.getLevelPartManager().setLevel(level);
                        
                        //Lastlevel beallitasa
                        lastLevel = levelNumber;
                        
                    }
                catch(Exception ex)
                    {
                        //Logger.getLogger(Controller.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
                    }
                
		SkeletonLogger.logReturn();
                
                
                               
                //update view
                 LevelGraphicalEntity l = new LevelGraphicalEntity();
                 l.setLevel(application.getLevelPartManager().getLevel());            
            
                view.setLevelGraphicalEntity(l);
	}

}